In C++, exceptions are a powerful mechanism for handling unexpected or exceptional situations in code, such as runtime errors, exceptional conditions, or user-defined error scenarios. Exception handling allows to gracefully handle errors and prevent program from crashing. Here's an overview of exceptions in C++:
it can throw an exception using the throw keyword followed by an expression (typically an object) that represents the exception:
throw MyException("An error occurred.");
To catch an exception and handle it, use try and catch blocks. The try block contains the code that might throw an exception, and the catch block specifies the type of exception to catch and handles it:
try {
// Code that might throw an exception
throw MyException("An error occurred.");
}
catch (const MyException& e) {
// Handle the exception
std::cerr << "Exception caught: " << e.what() << std::endl;
}
C++ provides a set of standard exception classes in the <stdexcept> header, such as std::runtime_error, std::invalid_argument, and std::out_of_range. it can use these to handle common error conditions.
try {
int x = 10;
if (x < 0) {
throw std::invalid_argument("x must be non-negative.");
}
}
catch (const std::invalid_argument& e) {
std::cerr << "Invalid argument: " << e.what() << std::endl;
}
it can define custom exception classes by inheriting from std::exception or any of its derived classes and overriding the what() function to provide a description of the exception:
class MyException : public std::exception {
public:
MyException(const char* message) : msg(message) {}
const char* what() const noexcept override {
return msg.c_str();
}
private:
std::string msg;
};
it can rethrow exceptions to propagate them up the call stack:
try {
// Code that might throw an exception
throw MyException("An error occurred.");
}
catch (const MyException& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
// Rethrow the exception
throw; // Re-throws the caught exception
}
In C++17 and later, it can use finally blocks with the help of the std::uncaught_exceptions function to perform cleanup operations regardless of whether an exception was thrown or not.
try {
// Code that might throw an exception
}
catch (const MyException& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
finally {
// Cleanup code (C++17 and later)
}
C++ provides a hierarchy of standard exception classes that it can be used for various types of errors. These are derived from std::exception. it can catch exceptions at different levels of the hierarchy to handle them selectively.
try {
// Code that might throw an exception
}
catch (const std::exception& e) {
std::cerr << "Exception caught: " << e.what() << std::endl;
}
Exception handling in C++ is a powerful mechanism for building robust and reliable software. It allows to gracefully handle errors and recover from exceptional situations while keeping code organized and maintainable.
A sample code with sample output using exception cases
#include <iostream>
#include <stdexcept>
// Custom exception class
class MyException : public std::exception {
public:
MyException(const char* message) : msg(message) {}
const char* what() const noexcept override {
return msg.c_str();
}
private:
std::string msg;
};
int main() {
try {
// Exception case 1: Division by zero
int numerator = 10;
int denominator = 0;
if (denominator == 0) {
throw std::runtime_error("Division by zero.");
}
// Exception case 2: Using a custom exception
int age = -5;
if (age < 0) {
throw MyException("Age it cannot be negative.");
}
// Exception case 3: Out of range
int array[5] = {1, 2, 3, 4, 5};
int index = 10;
if (index < 0 || index >= 5) {
throw std::out_of_range("Index is out of range.");
}
}
catch (const std::runtime_error& e) {
std::cerr << "Runtime Error: " << e.what() << std::endl;
}
catch (const MyException& e) {
std::cerr << "Custom Exception: " << e.what() << std::endl;
}
catch (const std::out_of_range& e) {
std::cerr << "Out of Range Exception: " << e.what() << std::endl;
}
catch (const std::exception& e) {
std::cerr << "Generic Exception: " << e.what() << std::endl;
}
catch (...) {
std::cerr << "Unknown Exception" << std::endl;
}
std::cout << "Program continues after exception handling." << std::endl;
return 0;
}
Runtime Error: Division by zero.
Program continues after exception handling.
After handling exceptions, the program continues to execute, demonstrating how exceptions allow to gracefully recover from errors without crashing the program.
This example shows how to use standard exceptions and custom exceptions to handle different types of exceptional situations in code.
question
question2